/*jslint browser: true, devel: true, bitwise: true, white: true, plusplus: true, forin:true, nomen:true */
/*global $:true, define:true */

/**
 * @module Test
 * @main Test
 */

define(['WID/Test/TestCase'],function(TestCase) {
"use strict";

/** 
 * 
 * @class Suite
 * @constructor
 */
function Suite(path, parent, reporter, data, doneCallback) {
	this.Path = path+'/';
	this.Parent = parent;
	this.Reporter = reporter;
	this.Data = data;
	this.DoneCallback = doneCallback;
	
	this.Current = 0;
	this.SubAmount = (data.suites)?data.suites.length:0;
	this.Cases = (data.cases)?true:false;
	this.CaseProcessor = new TestCase(reporter); 
}

Suite.MAINFILE = '/main.suite';
Suite.prototype = {
	constructor: Suite,
	
	exec: function() {
		if (!this.Parent) {
			this.Reporter.reportStarted();
		}
		
		this.Reporter.suiteStarted({
			name:this.Data.name,
			desc:this.Data.desc
		});
		
		this.execData();
	},
	
	execData: function() {
		if (this.Data.suites) {
			this.execSuites();
		} else if (this.Cases) {
			this.execCases();
		}
	},
	
	execSuites: function() {
		var 
			context = this,
			data = this.Data.suites,
			paths = this.createPaths(data,Suite.MAINFILE);
			
		require(paths, function() {
			context.SubData = arguments;
			var suite = new Suite(data[0],context,context.Reporter,context.SubData[0]);
			suite.exec();
		});
	},
	
	createPaths: function(names,end) {
		var paths = [], i,len = names.length;
		for (i = 0; i < len; ++i) {
			paths[i] = this.Path+names[i]+end;	
		}
		return paths;
	},
	
	subDone: function() {
		if (--this.SubAmount <= 0) {
			if (this.Cases) {
				this.execCases();
			} else {
				this.Reporter.suiteDone();
				if (this.Parent) {
					this.Parent.subDone();
				} else {
					this.done();
				}
			}
		} else {
			var suite = new Suite(this.Data.suites[++this.Current],this,this.Reporter,this.SubData[this.Current]);
			suite.exec();
		}
	},
	
	execCases: function() {
		var context = this;
		require(this.createPaths(this.Data.cases,'.case'),function() {
				var i, len = arguments.length;
				for (i = 0; i < len; ++i) {
					context.CaseProcessor.exec(arguments[i]);
				}
				context.Cases = false;
				context.subDone();
			});
	},
	
	done: function() {
		this.Reporter.reportDone();
	}
};

return Suite;
});
